package com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.repository;

import com.iwhalecloud.citybrain.flow.platform.manager.application.common.context.MessageSenderContext;
import com.iwhalecloud.citybrain.flow.platform.manager.application.service.BaseProcessService;
import com.iwhalecloud.citybrain.flow.platform.manager.application.service.MessageSenderManager;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.FlowUtils;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.MessageFillUtils;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.enums.CommentTypeEnum;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowProcessInstanceTraceVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.task.CommentVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.*;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.common.AddHisCommentCmd;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.mapper.IFlowableCommentDao;
import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Description: 添加历史审批记录
 * @Author: zhangnn
 * @description: 流程备注service
 * @date 202/11/26
 */
@Service
public class FlowableCommentServiceImpl extends BaseProcessService implements IFlowableCommentService {

    @Autowired
    private IFlowableCommentDao flowableCommentDao;
    @Autowired
    private FlowNoticeTemplateRepository flowNoticeTemplateRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private MessageSenderManager senderManager;
    @Autowired
    private FlowProcessInstanceTraceRepository processInstanceTraceRepository;

    @Override
    public void addComment(CommentVo comment) {
        managementService.executeCommand(new AddHisCommentCmd(comment.getTaskId(), comment.getUserId(), comment.getProcessInstanceId(),
                comment.getType(), comment.getMessage()));
    }

    @Override
    public List<CommentVo> getFlowCommentVosByProcessInstanceId(String processInstanceId) {
        List<CommentVo> datas = flowableCommentDao.getFlowCommentVosByProcessInstanceId(processInstanceId);
        datas.forEach(commentVo -> {
            commentVo.setTypeName(CommentTypeEnum.getEnumMsgByType(commentVo.getType()));
        });
        return datas;
    }

    @Override
    public void sendMessage(String taskId, String userCode, String processInstanceId, String turnToUserCode,String messageType,String title,String content) {
        FlowProcessInstanceTraceVo pt = processInstanceTraceRepository.getProcessInstanceTraceByProcessInstanceId(processInstanceId);
        Map<String, Object> map = resolveTemplateParams(taskId,pt, userCode,turnToUserCode);
        MessageSenderContext build = MessageSenderContext.builder()
                .processInstanceId(processInstanceId)
                .title(MessageFillUtils.replaceWithMap(title, map))
                .body(MessageFillUtils.replaceWithMap(content, map))
                .processName(pt.getModelName())
                .senderCode(userCode)
                .senderName(FlowUtils.getInstance().getReceiverName(userCode))
                .taskId(taskId)
                .type(messageType)
                .receiverCode(turnToUserCode)
                .receiverName(FlowUtils.getInstance().getReceiverName(turnToUserCode))
                .build();
        senderManager.send(build);
    }

    private Map<String, Object> resolveTemplateParams(String taskId,FlowProcessInstanceTraceVo pt, String userCode,String turnToUserCode) {
        Map<String, Object> result = new HashMap<>(8);
        TaskEntityImpl currTask = (TaskEntityImpl) taskService.createTaskQuery().taskId(taskId).singleResult();
        if (Objects.nonNull(currTask)) {
            result.put("taskName", currTask.getName());
        }
        if (Objects.nonNull(pt)){
            result.put("processName", pt.getModelName());
        }
        result.put("currentHandler", turnToUserCode);
        result.put("originator", userCode);
        return result;
    }
}
